import 'package:audioplayers/audioplayers.dart';
import 'package:jingyuan/commmon/LocalStorage.dart';
import 'package:jingyuan/commmon/EventBus.dart';
import 'package:jingyuan/commmon/GlobalData.dart';
import 'package:jingyuan/commmon/Utils.dart';

typedef TOnPlayDurationChanged = Function(int v);

class PlayerManager {
  PlayerManager(this.cfgKey, this.onChanged) {
    _init();
  }

  String cfgKey;
  Map<String, dynamic>? _currItem;
  final _player = AudioPlayer();
  Duration? _currPos;
  TOnPlayDurationChanged? onChanged;
  bool _isPlaying = false;

  _init() async {
    _currItem = await LocalStorage.getJson(currCfgKey);
    _player.onPositionChanged.listen((event) {
      _currPos = event;
      if (onChanged != null) {
        LocalStorage.setInt(currPosCfgKey, event.inSeconds);
        onChanged!(event.inSeconds);
      }
    });
    _player.onPlayerComplete.listen((event) {
      _currPos = null;
      FishEventBus.fire(PlayCompleteEvent(_currItem!["url"], this));
    });
    FishEventBus.on<PlayEvent>().listen((event) {
      if (_currItem != null) {
        String myUrl = _currItem!["url"] as String;
        if (event.url.isNotEmpty && myUrl.isNotEmpty && event.url.compareTo(myUrl) != 0) {
          pause();
        }
      }
    });

    var tempCurrPos = await LocalStorage.getInt(currPosCfgKey);
    if (tempCurrPos != null) {
      if (tempCurrPos > totalLengthInSeconds) {
        tempCurrPos = 0;
      }
      _currPos = Duration(seconds: tempCurrPos);
      if (onChanged != null) {
        onChanged!(tempCurrPos);
      }
    }
  }
  setCurrentItemWithoutPlay(Map<String, dynamic> item) {
    _currItem = item;
    _save();
  }

  play(Map<String, dynamic> item) async {
    var preUrl = "";
    if (_currItem != null) {
      preUrl = _currItem!["url"];
    }
    _currItem = item;
    String url = item["url"];
    if (preUrl != url) {
      // 重置开始位置为0
      _currPos = Duration.zero;
    }
    GlobalData.currPlayingTab = cfgKey;
    var fullUrl = Uri.encodeFull(Utils.appendUrl(GlobalData.urlBase, url));
    _player.play(UrlSource(fullUrl));
    if (_currPos != null) {
      _player.seek(_currPos!);
    }
    _save();

    _isPlaying = true;
    FishEventBus.fire(PlayEvent(url));
  }

  setPos(int pos) async {
    if (_currItem != null) {
      await resume();
      await _player.seek(Duration(seconds: pos));
    }
  }

  bool get isPlaying {
    return _isPlaying;
  }

  int get playedLengthInSeconds {
    if (_currPos == null) return 0;
    return _currPos!.inSeconds;
  }

  int get totalLengthInSeconds {
    if (_currItem == null) return 0;
    return _currItem!["len"] ~/ 1000;
  }

  resume() async {
    if (_player.state == PlayerState.paused) {
      GlobalData.currPlayingTab = cfgKey;
      String url = _currItem!["url"];
      await _player.resume();
      _isPlaying = true;
      FishEventBus.fire(PlayEvent(url));
    } else {
      if (_currItem != null) return await play(_currItem!);
    }
  }

  pause() {
    _player.pause();
    GlobalData.currPlayingTab = "";
    _isPlaying = false;
    FishEventBus.fire(PlayEvent(""));
  }

  Map<String, dynamic>? get currItem {
    return _currItem;
  }

  _save() {
    LocalStorage.setJson(currCfgKey, _currItem);
  }

  String get currCfgKey {
    return "${cfgKey}_currCfg";
  }

  String get currPosCfgKey {
    return "${cfgKey}_currPos";
  }

  void dispose() {
    _player.dispose();
  }
}
